package steven.savior.report.helper.impl;

import static steven.savior.report.helper.util.Constant.COLUMN_PART_NO;
import static steven.savior.report.helper.util.Constant.SHEET_EMPTY_PART_NO;
import static steven.savior.report.helper.util.Constant.SHEET_RAW;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import steven.savior.report.helper.api.ReportHelper;
import steven.savior.report.helper.exception.ReportHelperException;

/**
 * @author Chan Kin Wing
 *         bestwing@gmail.com
 *
 */
public class EmptyPartNoHelperImpl implements ReportHelper {
	private final Log logger = LogFactory.getLog(getClass());

	private static final int NOT_FOUND = -1;

	@Override
	public void process(String filePath, String targetPath) {
		logger.info("Processing file> filePath: " + filePath + ", targetPath: " + targetPath);
		POIFSFileSystem fs = null;
		FileOutputStream fileOut = null;
		try {
			logger.info("Opening source file: " + filePath);
			fs = new POIFSFileSystem(new FileInputStream(filePath));
			fileOut = new FileOutputStream(targetPath);
			HSSFWorkbook saleOrderWorkbook = new HSSFWorkbook(fs);

			logger.info("Locating sheet...");
			HSSFSheet rawSheet = saleOrderWorkbook.getSheet(SHEET_RAW);
			HSSFSheet emptyPartNoSheet = saleOrderWorkbook.getSheet(SHEET_EMPTY_PART_NO);

			int partNoColNum = getColumnNumByCellValue(rawSheet, 0, COLUMN_PART_NO);
			int rawRowNum = NOT_FOUND;
			int emptyPartNoRowNum = emptyPartNoSheet.getLastRowNum() + 1;
			do {
				rawRowNum = getEmptyPartNoRowNum(rawSheet, partNoColNum);
				if (rawRowNum != NOT_FOUND) {
					HSSFRow sourceRow = rawSheet.getRow(rawRowNum);
					HSSFRow targetRow = emptyPartNoSheet.createRow(emptyPartNoRowNum++);
					HSSFRow sampleRow = emptyPartNoSheet.getRow(1);
					targetRow.setHeight(sampleRow.getHeight());
					if (sourceRow.getRowStyle() != null) {
						targetRow.setRowStyle(sampleRow.getRowStyle());
					}
					for (int m = sourceRow.getFirstCellNum(); m < sourceRow.getLastCellNum(); m++) {
						HSSFCell sourceCell = sourceRow.getCell(m);
						HSSFCell targetCell = targetRow.createCell(m);
						HSSFCell sampleCell = targetRow.getCell(m);
						try {
							targetCell.setCellStyle(sampleCell.getCellStyle());
							targetCell.setCellType(sampleCell.getCellType());
						} catch (NullPointerException e) {

						}
						if (sourceCell != null) {
							targetCell.setCellValue(sourceCell.toString());
						}
					}
					rawSheet.removeRow(rawSheet.getRow(rawRowNum));
					rawSheet.shiftRows(rawRowNum + 1, rawSheet.getLastRowNum(), -1);
				}
			} while (rawRowNum != NOT_FOUND);
			// output file
			logger.info("Writing result to target file: " + targetPath);
			saleOrderWorkbook.write(fileOut);
		} catch (FileNotFoundException e) {
			throw new ReportHelperException(e.getMessage());
		} catch (IOException e) {
			throw new ReportHelperException(e.getMessage());
		} finally {
			try {
				fileOut.flush();
				fileOut.close();
			} catch (IOException e) {
				throw new ReportHelperException(e.getMessage());
			}
		}

	}

	private int getEmptyPartNoRowNum(HSSFSheet sheet, int colIndex) {
		int rowNum = NOT_FOUND;
		for (int i = 1; i < sheet.getLastRowNum(); i++) {
			HSSFRow row = sheet.getRow(i);
			if (row != null) {
				HSSFCell cell = row.getCell(colIndex);
				if (cell == null) {
					rowNum = i;
					break;
				}
			}
		}
		return rowNum;
	}

	private int getColumnNumByCellValue(HSSFSheet sheet, int rowNum, String cellVal) {
		int colNum = NOT_FOUND;
		HSSFRow row = sheet.getRow(rowNum);
		for (int i = 0; i < row.getLastCellNum(); i++) {
			HSSFCell cell = row.getCell(i);
			if (cell != null) {
				String value = cell.toString();
				if (value.equals(cellVal)) {
					colNum = i;
					break;
				}
			}
		}
		if (colNum == NOT_FOUND) {
			throw new ReportHelperException("<" + cellVal + "> dose not found.");
		}
		return colNum;
	}
}
